/*
 * Copyright (C) 2015 yixun All Rights Reserved.
 *
 * AreaServiceImpl.java
 */
package com.yixun.qfbao.api.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yixun.qfbao.api.service.*;
import com.yixun.qfbao.apidto.*;
import com.yixun.qfbao.apidto.base.CommonResDTO;
import com.yixun.qfbao.apidto.v10dto.FirsthandIntentionRevisitReqDto;
import com.yixun.qfbao.apidto.v10dto.SyncChannelIntentionStatusDTO;
import com.yixun.qfbao.apidto.v10dto.UpdateFirsthandIntentionAuditStatusReqDto;
import com.yixun.qfbao.apidto.v10dto.UpdateFirsthandIntentionTradeStatusReqDto;
import com.yixun.qfbao.config.V10ApiConfig;
import com.yixun.qfbao.constant.StringConstant;
import com.yixun.qfbao.dao.ApiFailLogDao;
import com.yixun.qfbao.dao.ApiLogDao;
import com.yixun.qfbao.dao.DepartmentDao;
import com.yixun.qfbao.enums.QfSmsTemplateEnum;
import com.yixun.qfbao.model.Dictionary;
import com.yixun.qfbao.model.*;
import com.yixun.qfbao.model.dto.*;
import com.yixun.qfbao.model.enums.*;
import com.yixun.qfbao.service.CompanyService;
import com.yixun.qfbao.service.*;
import com.yixun.qfbao.util.*;
import com.yixun.qfbao.xf.model.CaseMember;
import com.yixun.qfbao.xf.model.CustomerPremises;
import com.yixun.qfbao.xf.model.Premises;
import com.yixun.qfbao.xf.model.dto.CaseMemberDto;
import com.yixun.qfbao.xf.model.dto.CustomerPremisesDto;
import com.yixun.qfbao.xf.model.dto.FollowUpListDto;
import com.yixun.qfbao.xf.model.enums.ConfirmStatusEnum;
import com.yixun.qfbao.xf.model.enums.CustomerStatusEnum;
import com.yixun.qfbao.xf.model.enums.DisableTypeEnum;
import com.yixun.qfbao.xf.model.enums.ResultEnum;
import com.yixun.qfbao.xf.service.CaseMemberService;
import com.yixun.qfbao.xf.service.CustomerPremisesService;
import com.yixun.qfbao.xf.service.FollowUpListService;
import com.yixun.qfbao.xf.service.PremisesService;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.GeneralSecurityException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * [文件名称]<br>
 * CPReportServiceImpl.java<br>
 * <br>
 * [文件描述]<br>
 * 报备相关<br>
 * <br>
 *
 * @author JHSong
 * @version 1.00
 */
@Service
public class ReportCommonServiceImpl implements ReportCommonService {

    private Logger logger = LoggerFactory.getLogger(CPReportServiceImpl.class);

    @Autowired
    private SMSUtil smsUtil;
    @Autowired
    V10ApiConfig v10ApiConfig;
    @Autowired
    private AffixService affixService;
    @Autowired
    private PartnerInfoService partnerInfoService;
    @Autowired
    private CompanyService companyService;
    @Autowired
    private DepartmentDao departmentDao;
    @Autowired
    private PremisesService premisesService;
    @Autowired
    private CustomerPremisesService customerPremisesService;
    @Autowired
    private FollowUpListService followUpListService;
    @Autowired
    private CaseMemberService caseMemberService;
    @Autowired
    private DictionaryService dictionaryService;
    @Autowired
    private SmsHistoryService smsHistoryService;
    @Autowired
    private V10BindService v10BindService;
    @Autowired
    private ReportExternalService reportExternalService;
    @Autowired
    private WxTemplateMsgService wxTemplateMsgService;
    @Autowired
    private WeAppMessageService weAppMessageService;

    @Autowired
    private EstateAdviserService estateAdviserService;

    @Autowired
    private ApiLogDao apiLogDao;

    @Autowired
    private ApiFailLogDao apiFailLogDao;

    /**
     * 校验M2关联上商户,是否存在该用户
     *
     * @param projectCodeM2
     * @param merchantCode
     * @param customerPhone
     * @param m2RequestUrl
     * @return
     */
    @Override
    public CommonResDTO isExistsInM2(String projectCodeM2, String merchantCode, String customerPhone, String m2RequestUrl) {
        CommonResDTO resDto = new CommonResDTO();
        resDto.setResult(ResultEnum.FAIL.getNo());
        resDto.setResultMsg("M2手机号校验失败!");
        //是否存在M2商户号: 存在: 与M2有关联、不存在: 与M2无关联,无需校验
        if (StringUtils.isEmpty(merchantCode)) {
            return resDto;
        }

        //校验客户在M2是否重复
        if (StringUtils.isNotEmpty(projectCodeM2)) {
            Map<String, String> map = new HashMap<String, String>();
            map.put("merchantCode", merchantCode);
            map.put("token", merchantCode);
            map.put("projectCode", projectCodeM2);
            map.put("customerPhone", customerPhone);
            map.put("version", null);
            String signStr = EncryptUtil.createLinkString(map);
            String sign = EncryptUtil.Encrypt(signStr, "MD5");
            map.put("sign", sign);
            //组装Params参数
            Map<String, Object> paramsMap = new HashMap<String, Object>();
            paramsMap.put("params", map);
            com.alibaba.fastjson.JSONObject json = new com.alibaba.fastjson.JSONObject(paramsMap);
            String jsonStr = json.toString();
            //组装参数body
            Map<String, String> body = new HashMap<String, String>();
            body.put("body", jsonStr);
            String resStr = null;
            try {
                String url = m2RequestUrl + M2RequestEnum.CUS_UNIQUE.getNo();
                resStr = RequestUtil.buildRequest(url, body, "UTF-8");
                if (StringUtils.isNotEmpty(resStr) && isJSONValid(resStr)) {
                    com.alibaba.fastjson.JSONObject jsonObject = com.alibaba.fastjson.JSONObject.parseObject(resStr);
                    String resDataStr = jsonObject.getString("resData");
                    com.alibaba.fastjson.JSONObject resDataJson = com.alibaba.fastjson.JSONObject.parseObject(resDataStr);
                    String result = resDataJson.getString("result");
                    if ("1".equals(result)) {
                        String isExists = resDataJson.getString("isExists");
                        if ("true".equals(isExists)) {
                            resDto.setResultMsg("手机号:" + customerPhone + ",已在M2系统中存在!");
                            return resDto;
                        } else {
                            resDto.setResult(ResultEnum.SUCCESS.getNo());
                        }
                    }
                }
            } catch (HttpException e) {
                logger.error("isExistsInM2 error: {}", e);
            } catch (UnsupportedEncodingException e) {
                logger.error("isExistsInM2 error: {}", e);
            } catch (GeneralSecurityException e) {
                logger.error("isExistsInM2 error: {}", e);
            } catch (Exception e) {
                logger.error("isExistsInM2 error: {}", e);
            }
        }
        return resDto;
    }

    @Override
    public void setReportProtectOverDueTime(CustomerPremisesDto cpDto, ReportProtectOverDueDto reportProtectOverDueDto) {
        Calendar calendar = Calendar.getInstance();
        cpDto.setReportPeriodTime(calendar.getTime());
        if (Objects.nonNull(reportProtectOverDueDto)) {
            Long reportProtect = reportProtectOverDueDto.getProtectTime();
            if (Objects.nonNull(reportProtect)) {
                calendar.add(Calendar.MINUTE, Integer.valueOf(String.valueOf(reportProtect)));
                cpDto.setReportPeriodTime(calendar.getTime());
            }
        }
    }

    @Override
    public void setReportValidOverDueTime(CustomerPremisesDto cpDto, ReportValidOverDueDto reportValidOverDueDto) {
        cpDto.setReportValidTime(null);
        if (Objects.nonNull(reportValidOverDueDto)) {
            Long reportValid = reportValidOverDueDto.getValidTime();
            if (Objects.isNull(reportValid) || cpDto.getMobile().indexOf(StringConstant.THREE_STAR) >= 0) {
                cpDto.setReportValidTime(null);
            } else {
                Calendar calendar = Calendar.getInstance();
                calendar.add(Calendar.MINUTE, Integer.valueOf(String.valueOf(reportValid)));
                cpDto.setReportValidTime(calendar.getTime());
            }
        }
    }

    @Override
    public void addReportFollow(CustomerPremisesDto cpDto, String followType, String reportPrefix, String staffId, String remark) {
        //写带状态跟进记录
        FollowUpListDto fulDto = new FollowUpListDto();
        fulDto.setCreateTime(Calendar.getInstance().getTime());
        fulDto.setCustomerPremisesId(cpDto.getId());
        fulDto.setNewConfirmStatus(ConfirmStatusEnum.confirm.getNo());
        fulDto.setNewCustomerStatus(CustomerStatusEnum.normal.getNo());
        fulDto.setStaffId(Long.valueOf(staffId));
        fulDto.setFollowType(followType);
        if (StringUtils.isNotBlank(remark)) {
            fulDto.setRemark("【" + reportPrefix + "】" + remark);
        } else {
            fulDto.setRemark("【" + reportPrefix + "】");
        }
        followUpListService.create(fulDto);
    }

    @Override
    public void sendReportSms(Premises premises, PartnerInfo assistantPi, Map<String, String> smsMap, CustomerPremisesDto cpDto, String remark) {
        //查询楼盘相关案场助手人员,发短信用
        CaseMemberDto cmDto = new CaseMemberDto();
        cmDto.setPremisesId(premises.getId());
        cmDto.setPiStatus(MechanismStatusEnum.enable.getNo());
        cmDto.setSmsStatus("1");
        List<CaseMember> cmList = new ArrayList<CaseMember>();
        boolean flag = companyService.getMessageFlag(premises.getCompanyId());
        logger.info("商户 [ " + premises.getCompanyId() + "], 短信通道是否打开: " + flag);
        if (flag) {
            //需要发短信，就查询接收短信相关人员
            cmList = caseMemberService.selectListByDto(cmDto);
        }
        //发送短信
        try {
            if (null != cmList && cmList.size() > 0) {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                //报备客户,给楼盘对应的管理员发送短信
                String smsSwitch = smsUtil.getSmsSwitch();
                if (StringUtils.isNotEmpty(smsSwitch) && "T".equals(smsSwitch)) {
                    String smsTemp = SMSTypeEnum.TYPE_01.getNo();
                    DictionaryDto dicDto = new DictionaryDto();
                    dicDto.setDicType(smsTemp);
                    Dictionary dic = dictionaryService.selectByDto(dicDto);
                    if (null != dic) {
                        for (CaseMember cm : cmList) {
                            String hopeVisitTime = "";
                            if (null != cpDto.getHopeVisitTime()) {
                                hopeVisitTime = sdf.format(cpDto.getHopeVisitTime());
                            }
                            String receiveMobile = "";
                            PartnerInfo cmPi = partnerInfoService.selectById(cm.getPartnerId());
                            if (null != cmPi) {
                                receiveMobile = cmPi.getPhone();
                            }
                            if (StringUtils.isEmpty(receiveMobile)) {
                                continue;
                            }
                            String smsContent = dic.getDicValue();
                            DepartmentDto departDto = departmentDao.getPrincipal(cpDto.getStaffId());
                            String principalName = "";
                            if (departDto != null) {
                                principalName = departDto.getPrincipalName();
                            }
                            String premisesName = smsMap.get("premisesName");
                            String agentCompany = smsMap.get("agentCompany");
                            String agentDept = smsMap.get("agentDept");
                            String agentName = smsMap.get("agentName");
                            String agentPhone = smsMap.get("agentPhone");
                            String cusName = smsMap.get("cusName");
                            String mobile = smsMap.get("mobile");
                            if (StringUtils.isBlank(principalName)) {
                                //当对接人为空时
                                smsContent = smsContent.replace("对接人:%s，", "");
                                smsContent = String.format(smsContent, premisesName, agentCompany, agentDept, agentName, agentPhone, cusName, mobile, hopeVisitTime);
                            } else {
                                smsContent = String.format(smsContent, premisesName, principalName, agentCompany, agentDept, agentName, agentPhone, cusName, mobile, hopeVisitTime);
                            }
                            //获取短信设置,功能已变更.设置已用于定制化号码验真.此处不能保留
                            Map<String, String> smsSettingMap = null;
                            Map<String, String> qfSmsMap = new HashMap<>();
                            qfSmsMap.put("key1", premisesName);
                            qfSmsMap.put("key2", StringUtils.isBlank(principalName) ? "无" : principalName);
                            qfSmsMap.put("key3", agentCompany);
                            qfSmsMap.put("key4", agentDept);
                            qfSmsMap.put("key5", agentName);
                            qfSmsMap.put("key6", agentPhone);
                            qfSmsMap.put("key7", cusName);
                            qfSmsMap.put("key8", mobile);
                            qfSmsMap.put("key9", hopeVisitTime);

                            Map<String, Object> returnMap = smsUtil.sendMessage(smsContent, receiveMobile, QfSmsTemplateEnum.SMS_AGENCY_REPORT.getId(), smsSettingMap, qfSmsMap);
                            boolean sendStatus = (Boolean) returnMap.get("sendStatus");
                            String sendRes = String.valueOf(returnMap.get("sendRes"));

                            SmsHistoryDto smsHis = new SmsHistoryDto();
                            smsHis.setSender(smsUtil.getUserName());
                            if (null != smsSettingMap) {
                                smsHis.setSender(smsSettingMap.get("userName"));
                            }
                            smsHis.setReceiver(receiveMobile);
                            smsHis.setContent(smsContent);
                            smsHis.setSendStatus(sendStatus ? SendStatusEnum.SUCCESS.getNo() : SendStatusEnum.FAILURE.getNo());
                            smsHis.setSendRes(sendRes);
                            smsHis.setMerchantId(cmPi.getHigherid());
                            smsHis.setRemark(remark);
                            smsHis.setCreateUserId(assistantPi.getId());
                            if (returnMap.containsKey("orderUuid")) {
                                smsHis.setOrderUuid(String.valueOf(returnMap.get("orderUuid")));
                            }
                            if (returnMap.containsKey("platform")) {
                                smsHis.setPlatform(String.valueOf(returnMap.get("platform")));
                            }
                            smsHistoryService.create(smsHis);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("sendReportSms error: {}", e);
        }
    }

    @Override
    public void setAuditFollow(PartnerInfo pi, Long customerPremisesId, Map<String, String> statusMap, String disableType, String operFollowRemark, List<AffixDto> affixList, String optType) {
        String oldCustomerStatus = statusMap.get("oldCustomerStatus");
        String newCustomerStatus = statusMap.get("newCustomerStatus");
        String oldConfirmStatus = statusMap.get("oldConfirmStatus");
        String newConfirmStatus = statusMap.get("newConfirmStatus");

        FollowUpListDto followDto = new FollowUpListDto();
        followDto.setStaffId(pi.getId());
        followDto.setCustomerPremisesId(customerPremisesId);
        followDto.setOldConfirmStatus(oldConfirmStatus);
        followDto.setNewConfirmStatus(newConfirmStatus);
        followDto.setOldCustomerStatus(oldCustomerStatus);
        followDto.setNewCustomerStatus(newCustomerStatus);
        followDto.setRemark(operFollowRemark);
        followDto.setFollowType(FollowTypeEnum.CHANNEL.getNo());
        if (CustomerStatusEnum.has_visited.getNo().equals(newCustomerStatus)) {
            followDto.setVisitedCount(1);
        }
        followDto = followUpListService.create(followDto);

        // 保存跟进附件
        String affixType = AffixTypeEnum.AUDIT.toString();
        if (OperationTypeEnum.OPERATIONTYPE_3.getCode().equalsIgnoreCase(optType)) {
            switch (CustomerStatusEnum.getByNo(newCustomerStatus)) {
                case not_visited:
                    affixType = AffixTypeEnum.AUDIT.toString();
                    break;
                case has_visited:
                    affixType = AffixTypeEnum.VISIT.toString();
                    break;
                case no_valid:
                    if(Objects.nonNull(DisableTypeEnum.getByNo(disableType))){
                        switch (DisableTypeEnum.getByNo(disableType)) {
                            case report_invalid:
                                affixType = AffixTypeEnum.AUDIT_INVALID.toString();
                                break;
                            case visit_invalid:
                                affixType = AffixTypeEnum.VISIT_INVALID.toString();
                                break;
                            default:
                                break;
                        }
                    }
                    break;
                default:
                    break;
            }
        } else if (OperationTypeEnum.OPERATIONTYPE_2.getCode().equals(optType)) {
            switch (ConfirmStatusEnum.getByNo(newConfirmStatus)) {
                case payDeposit:
                    affixType = AffixTypeEnum.RESERVE.toString();
                    break;
                case subscribe:
                    affixType = AffixTypeEnum.SUBSCRIBE.toString();
                    break;
                case sign:
                    affixType = AffixTypeEnum.SIGN.toString();
                    break;
                case sign_fail:
                    if(Objects.nonNull(DisableTypeEnum.getByNo(disableType))){
                        switch (DisableTypeEnum.getByNo(disableType)) {
                            case PAYDEPOSIT_FAILD:
                                affixType = AffixTypeEnum.RESERVE_FAIL.toString();
                                break;
                            case SUBSCRIBE_FAILD:
                                affixType = AffixTypeEnum.SUBSCRIBE_FAIL.toString();
                                break;
                            case SIGN_FAILD:
                                affixType = AffixTypeEnum.SIGN_FAIL.toString();
                                break;
                            default:
                                break;
                        }
                    }
                    break;
                default:
                    break;
            }
        }

        if (!CollectionUtils.isEmpty(affixList)) {
            for (AffixDto dto : affixList) {
                dto.setReportId(customerPremisesId);
                dto.setFollowUpListId(followDto.getId());
                dto.setAffixUuid(UUID.randomUUID().toString());
                dto.setAffixType(affixType);
            }
            affixService.addAffixBatch(affixList);
        }
    }

    @Async
    @Override
    public void sendAuditCPSms(PartnerInfo assistantPi, CustomerPremises customerPremises) {
        //查询楼盘相关案场助手人员,发短信用
        CaseMemberDto cmDto = new CaseMemberDto();
        cmDto.setPremisesId(customerPremises.getPremisesId());
        cmDto.setPiStatus(MechanismStatusEnum.enable.getNo());
        cmDto.setSmsStatus("1");
        List<CaseMember> cmList = new ArrayList<CaseMember>();
        boolean flag = companyService.getMessageFlag(assistantPi.getHigherid());
        logger.info("商户 [ " + assistantPi.getHigherid() + "], 短信通道是否打开: " + flag);
        if (flag) {
            //需要发短信，就查询接收短信相关人员
            cmList = caseMemberService.selectListByDto(cmDto);
        }
        PartnerInfo reportPartner = partnerInfoService.selectById(customerPremises.getStaffId());
        Premises premises = premisesService.selectSimpleById(customerPremises.getPremisesId());
        //发送短信
        try {
            if (null != cmList && cmList.size() > 0) {
                //报备客户,给楼盘对应的管理员发送短信
                String smsSwitch = smsUtil.getSmsSwitch();
                if (StringUtils.isNotEmpty(smsSwitch) && "T".equals(smsSwitch)) {
                    String smsTemp = SMSTypeEnum.TYPE_01.getNo();
                    DictionaryDto dicDto = new DictionaryDto();
                    dicDto.setDicType(smsTemp);
                    Dictionary dic = dictionaryService.selectByDto(dicDto);
                    if (null != dic) {
                        // 添加报备人进来,一起发送短信
                        // 将经纪人的Id、楼盘的公司存入到CaseMember
                        CaseMember reportCm = new CaseMember();
                        reportCm.setPartnerId(reportPartner.getId());
                        reportCm.setCompanyId(premises.getCompanyId());
                        cmList.add(reportCm);
                        String reportPi = String.valueOf(reportPartner.getId());
                        for (CaseMember cm : cmList) {
                            String receiveMobile = "";
                            PartnerInfo cmPi = partnerInfoService.selectById(cm.getPartnerId());
                            if (null != cmPi) {
                                receiveMobile = cmPi.getPhone();
                            }
                            //如果是报备人的时候 receiveMobile 先从报备表里面取
                            if (cm.getId() == null && cm.getPartnerId().equals(reportPartner.getId())) {
                                if (StringUtils.isNotBlank(customerPremises.getReportPhone())) {
                                    receiveMobile = customerPremises.getReportPhone();
                                }
                            }
                            if (StringUtils.isEmpty(receiveMobile)) {
                                continue;
                            }

                            long smsCompany = cmPi.getHigherid();
                            if (reportPi.equals(String.valueOf(cm.getPartnerId()))) {
                                smsCompany = cm.getCompanyId();
                            }

                            //客户姓名
                            String cusName = customerPremises.getName();
                            //客户手机号
                            String cusPhone = customerPremises.getMobile();
                            //到访时间: 当前时间
                            String currTime = DateUtils.DateToString(Calendar.getInstance().getTime(), DateStyle.YYYY_MM_DD_HH_MM_SS);
                            //楼盘名称
                            String premisesName = premises.getName();
                            //置业顾问
                            String guwenName = assistantPi.getAccountName();
                            //经纪人
                            String agentName = reportPartner.getAccountName();
                            //经纪人手机号
                            String agentPhone = reportPartner.getPhone();
                            //获取短信设置,功能已变更.设置已用于定制化号码验真.此处不能保留
                            Map<String, String> smsSettingMap = null;
                            Map<String, String> qfSmsMap = new HashMap<>();
                            qfSmsMap.put("key1", cusName);
                            qfSmsMap.put("key2", cusPhone);
                            qfSmsMap.put("key3", currTime);
                            qfSmsMap.put("key4", premisesName);
                            qfSmsMap.put("key5", guwenName);
                            qfSmsMap.put("key6", agentName);
                            qfSmsMap.put("key7", agentPhone);

                            Map<String, Object> returnMap = smsUtil.sendMessage("", receiveMobile, QfSmsTemplateEnum.SMS_WARN_AUDIT.getId(), smsSettingMap, qfSmsMap);
                            boolean sendStatus = (Boolean) returnMap.get("sendStatus");
                            String sendRes = String.valueOf(returnMap.get("sendRes"));

                            SmsHistoryDto smsHis = new SmsHistoryDto();
                            String smsContent = "客户已到访：到访确认申请！客户：%s %s，在%s看了%s，接待的置业顾问：%s。报备经纪人：%s %s！";
                            smsContent = String.format(smsContent, cusName, cusPhone, currTime, premisesName, guwenName, agentName, agentPhone);
                            smsHis.setSender(smsUtil.getUserName());
                            if (null != smsSettingMap) {
                                smsHis.setSender(smsSettingMap.get("userName"));
                            }
                            smsHis.setReceiver(receiveMobile);
                            smsHis.setContent(smsContent);
                            smsHis.setSendStatus(sendStatus ? SendStatusEnum.SUCCESS.getNo() : SendStatusEnum.FAILURE.getNo());
                            smsHis.setSendRes(sendRes);
                            smsHis.setMerchantId(smsCompany);
                            smsHis.setRemark("到访审核!");
                            smsHis.setCreateUserId(assistantPi.getId());
                            if (returnMap.containsKey("orderUuid")) {
                                smsHis.setOrderUuid(String.valueOf(returnMap.get("orderUuid")));
                            }
                            if (returnMap.containsKey("platform")) {
                                smsHis.setPlatform(String.valueOf(returnMap.get("platform")));
                            }
                            smsHistoryService.create(smsHis);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("isExistsInM2 error: {}", e);
        }
    }

    @Async
    @Override
    public void customerToM2(CustomerPremises customerPremises, String m2Url,String merchantCode) {
        if (StringUtils.isBlank(m2Url)) {
            return;
        }
        Premises premises = premisesService.selectSimpleById(customerPremises.getPremisesId());
        if (null == premises) {
            return;
        }
        CustomerPremisesDto cpDto = customerPremisesService.selectByMyId(customerPremises.getId());
        List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
        Map<String, String> map = new HashMap<String, String>(5);
        map.put("recommendedChannelId", customerPremises.getId().toString());
        map.put("userName", customerPremises.getName());
        map.put("phone", customerPremises.getMobile());
        map.put("projectCode", premises.getProjectCodeM2());
        map.put("remark", customerPremises.getRemark());
        map.put("agentCompany", cpDto.getStaffCompanyName());
        map.put("agentStoreName", cpDto.getStaffStoreName());
        map.put("agentGroupName", cpDto.getStaffGroupName());
        map.put("agentName", cpDto.getStaffName());
        map.put("agentPhone", cpDto.getStaffPhone());
        mapList.add(map);
        logger.info("customerToM2 同步M2 报备数据 request {}",map);
        // 组装接口入参
        JSONObject json = new JSONObject();
        // 版本号（备用）
        json.put("version", "");
        // token（备用）
        json.put("token", "");
        // 签名（备用）
        json.put("sign", "");
        json.put("customerList", mapList);
        // 访问m2接口
        String url = m2Url + M2RequestEnum.CUS_TOM2.getNo();
        //响应结果
        String result = "";
        // 执行状态
        boolean execStatus = true;
        try {
            // 执行接口请求
            result = HttpApi.doPostUrl(url, json);

            JSONObject obj = JSONObject.parseObject(result);
            // 解析返回数据
            ChannelToM2ResDto resM2 = JSONObject.parseObject(obj.get("resData") + "", ChannelToM2ResDto.class);
            logger.info("customerToM2 同步M2 报备数据 response {}",JSONObject.toJSONString(resM2));
            //添加ApiLog 日志信息
            ApiLogDto apiLogDto = new ApiLogDto();
            apiLogDto.setUrl(m2Url);
            apiLogDto.setBusinessType(ApiActionEnum.REPORT_M2.getNo());
            apiLogDto.setRequestType(2);
            apiLogDto.setRequestContent(JSONObject.toJSONString(json));
            apiLogDto.setPremisesId(premises.getId());
            apiLogDto.setPremisesName(premises.getName());
            apiLogDto.setCompanyId(premises.getCompanyId());
            apiLogDto.setOtherCompanyId(merchantCode);
            apiLogDto.setResponseContent(JSONObject.toJSONString(resM2));
            apiLogDao.create(apiLogDto);

            if (!ResultEnum.SUCCESS.getNo().equals(resM2.getResult())) {
                // 添加接口请求失败日志
                saveApiFailLog(m2Url,JSONObject.toJSONString(json),JSONObject.toJSONString(resM2),premises.getCompanyId(),premises.getId(),cpDto.getId());
                return;
            }
            // 获取未成功数据
            List<ChannelToM2Res> failList = resM2.getFailList();
            if (null != failList && failList.size() > 0) {
                return;
            }
        }catch (Exception e){
            logger.error("customerToM2 同步M2 error: {}", e);
            execStatus = false;
        }finally {
            if(!execStatus){
                // 口请求失败日志添加接
                saveApiFailLog(m2Url,JSONObject.toJSONString(json),result,premises.getCompanyId(),premises.getId(),cpDto.getId());
                return;
            }
        }

        // 将转客成功的数据标识为已转客
        CustomerPremisesDto update = new CustomerPremisesDto();
        update.setCustomerIds(Arrays.asList(customerPremises.getId().toString()));
        // 已转客
        update.setIsToM2("1");
        customerPremisesService.updateByIds(update);
    }

    /**
     * 添加请求失败日志
     * @param url
     * @param request
     * @param response
     * @param companyId
     * @param premisesId
     * @param businessId
     */
    void saveApiFailLog(String url, String request, String response, Long companyId, Long premisesId, Long businessId){
        ApiFailLog apiFailLog = new ApiFailLog();
        apiFailLog.setUrl(url);
        apiFailLog.setStatus(ResultEnum.FAIL.getNo());
        apiFailLog.setRequestContent(request);
        apiFailLog.setResponseContent(response);
        apiFailLog.setBusinessType(ApiActionEnum.REPORT_M2.getNo());
        apiFailLog.setCompanyId(companyId);
        apiFailLog.setPremisesId(premisesId);
        apiFailLog.setBusinessId(businessId);
        apiFailLog.setExecCount(0);
        apiFailLog.setBusinessTime(Calendar.getInstance().getTime());
        apiFailLogDao.addApiFailLog(apiFailLog);
    }

    @Override
    public int customerToM2Again(ApiFailLog apiFailLog) {
        if (null == apiFailLog){
            return 0;
        }
        if (StringUtils.isBlank(apiFailLog.getUrl())){
            return 0;
        }
        Premises premises = premisesService.selectSimpleById(apiFailLog.getPremisesId());
        if (null == premises) {
            logger.error("customerToM2Again 重新同步M2 楼盘不存在");
            return 0;
        }
        CustomerPremisesDto cpDto = customerPremisesService.selectByMyId(apiFailLog.getBusinessId());
        if (null == cpDto) {
            logger.error("customerToM2Again 重新同步M2 报备不存在");
            return 0;
        }
        logger.info("customerToM2Again 重新同步M2 报备数据 request {}",apiFailLog.getRequestContent());

        JSONObject json = JSONObject.parseObject(apiFailLog.getRequestContent());

        //响应结果
        String result = "";
        // 执行状态
        boolean execStatus = true;
        try {
            // 执行接口请求
            result = HttpApi.doPostUrl(apiFailLog.getUrl(), json);

            JSONObject obj = JSONObject.parseObject(result);
            // 解析返回数据
            ChannelToM2ResDto resM2 = JSONObject.parseObject(obj.get("resData") + "", ChannelToM2ResDto.class);
            logger.info("customerToM2 同步M2 报备数据 response {}",JSONObject.toJSONString(resM2));
            //添加ApiLog 日志信息
            ApiLogDto apiLogDto = new ApiLogDto();
            apiLogDto.setUrl(apiFailLog.getUrl());
            apiLogDto.setBusinessType(ApiActionEnum.REPORT_M2.getNo());
            apiLogDto.setRequestType(2);
            apiLogDto.setRequestContent(JSONObject.toJSONString(json));
            apiLogDto.setPremisesId(premises.getId());
            apiLogDto.setPremisesName(premises.getName());
            apiLogDto.setCompanyId(premises.getCompanyId());
            String merchantCode = companyService.isDevBindM2(String.valueOf(apiFailLog.getCompanyId()), CompanyTypeEnum.COMPANY_TYPE_VALUE_2.getCode());
            apiLogDto.setOtherCompanyId(merchantCode);
            apiLogDto.setResponseContent(JSONObject.toJSONString(resM2));
            apiLogDao.create(apiLogDto);

            if (!ResultEnum.SUCCESS.getNo().equals(resM2.getResult())) {
                // 修改接口请求失败日志
                apiFailLog.setExecCount(apiFailLog.getExecCount()+1);
                apiFailLog.setResponseContent(JSONObject.toJSONString(resM2));
                apiFailLogDao.updateApiFailLog(apiFailLog);
                return 0;
            }
            // 获取未成功数据
            List<ChannelToM2Res> failList = resM2.getFailList();
            if (null != failList && failList.size() > 0) {
                return 0;
            }

            // 更新失败日志转为成功
            apiFailLog.setStatus(ResultEnum.SUCCESS.getNo());
            apiFailLog.setExecCount(apiFailLog.getExecCount()+1);
            apiFailLog.setResponseContent(JSONObject.toJSONString(resM2));
            apiFailLogDao.updateApiFailLog(apiFailLog);
        }catch (Exception e){
            logger.error("customerToM2Again 重新同步M2 error: {}", e);
            execStatus = false;
        }finally {
            if(!execStatus){
                // 修改接口请求失败日志
                apiFailLog.setExecCount(apiFailLog.getExecCount()+1);
                apiFailLog.setResponseContent(result);
                apiFailLogDao.updateApiFailLog(apiFailLog);
                return 0;
            }
        }

        // 将转客成功的数据标识为已转客
        CustomerPremisesDto update = new CustomerPremisesDto();
        update.setCustomerIds(Arrays.asList(cpDto.getId().toString()));
        // 已转客
        update.setIsToM2("1");
        customerPremisesService.updateByIds(update);
        return 1;
    }

    @Override
    public void sendAuditWxMsg(CustomerPremises customerPremises, Map<String, String> statusMap, WxMsgCommonDto wxMsgCommonDto, String agToken, String asToken) {
        //微信小程序所需参数
        String companyUuid = wxMsgCommonDto.getCompanyUuid();
        String oldCustomerStatus = statusMap.get("oldCustomerStatus");
        String newCustomerStatus = statusMap.get("newCustomerStatus");
        String remark = wxMsgCommonDto.getRemark();

        Map<String, String> weappAgencyMsgMap = new HashMap<>();
        weappAgencyMsgMap.put("id", String.valueOf(customerPremises.getId()));
        weappAgencyMsgMap.put("staffId", String.valueOf(customerPremises.getStaffId()));
        weappAgencyMsgMap.put("premisesId", String.valueOf(customerPremises.getPremisesId()));
        weappAgencyMsgMap.put("customerName", customerPremises.getName());
        weappAgencyMsgMap.put("customerPhone", customerPremises.getMobile());
        weappAgencyMsgMap.put("createTime", DateUtils.DateToString(customerPremises.getCreateTime(), DateStyle.YYYY_MM_DD_HH_MM_SS));
        weappAgencyMsgMap.put("hopeVisitTime", Objects.isNull(customerPremises.getHopeVisitTime())?"":DateUtils.DateToString(customerPremises.getHopeVisitTime(), DateStyle.YYYY_MM_DD_HH_MM_SS));
        weappAgencyMsgMap.put("changeStatus", CustomerStatusEnum.getDescByNo(statusMap.get("newCustomerStatus")));
        weappAgencyMsgMap.put("changeTime", DateUtils.DateToString(new Date(), DateStyle.YYYY_MM_DD_HH_MM_SS));
        weappAgencyMsgMap.put("failureDesc", "有一条报备被驳回，如有误，您可以提出报备申诉");
        weappAgencyMsgMap.put("remark", remark);
        weappAgencyMsgMap.put("companyUuid", companyUuid);
        // 未到访提醒消息
        if (CustomerStatusEnum.not_visited.getNo().equals(newCustomerStatus)) {
            //审核成功，状态未到访 发送模板消息
            wxTemplateMsgService.sendReportSuccessTemplateMsg(agToken, asToken, customerPremises, wxMsgCommonDto);
            //报备审核成功小程序消息通知
            weAppMessageService.sendWeAppAgencyMsg(weappAgencyMsgMap, WeAppSendTypeEnum.AGENCY_AUDIT_SUCCESS.getNo());
        }
        // 已到访提醒消息
        if (CustomerStatusEnum.has_visited.getNo().equals(newCustomerStatus)) {
            //发送微信模板消息
            Date visitTime = customerPremises.getUpdateTime();// 到访时间为到访确认时间
            wxTemplateMsgService.sendVisitSuccessTemplateMsg(agToken, customerPremises, wxMsgCommonDto, visitTime);
            //到访审核成功小程序消息通知
            weAppMessageService.sendWeAppAgencyMsg(weappAgencyMsgMap, WeAppSendTypeEnum.AGENCY_TRADE_SUCCESS.getNo());
        }

        // 审核失败提醒消息
        if (CustomerStatusEnum.no_valid.getNo().equals(newCustomerStatus)) {
            // 除待审核变更为报备无效外,其余无效操作统一视为交易失败
            if (CustomerStatusEnum.normal.getNo().equals(oldCustomerStatus)) {
                //审核失败， 发送模板消息
                wxTemplateMsgService.sendReportRefueTemplateMsg(agToken, asToken, customerPremises, wxMsgCommonDto);
                //报备审核失败小程序消息通知
                weAppMessageService.sendWeAppAgencyMsg(weappAgencyMsgMap, WeAppSendTypeEnum.AGENCY_AUDIT_FAILURE.getNo());
            } else {
                // 原逻辑: CustomerStatusEnum.not_visited.getNo().equals(oldCustomerStatus) 才会发送如下消息
                // 现逻辑: 除报备审核失败以外,其余变更状态为无效的操作,都发送如下消息模板
                wxTemplateMsgService.sendDealFailTemplateMsg(agToken, asToken, wxMsgCommonDto,
                        customerPremises.getId(), customerPremises.getPremisesId() + "", customerPremises.getStaffId() + "", customerPremises.getName(), customerPremises.getMobile(),
                        remark);
                //到访审核失败小程序消息通知
                weAppMessageService.sendWeAppAgencyMsg(weappAgencyMsgMap, WeAppSendTypeEnum.AGENCY_TRADE_FAILURE.getNo());
            }
        }
    }

    @Override
    @Async
    public void sendConfirmWxMsg(CustomerPremises customerPremises, Map<String, String> statusMap, WxMsgCommonDto wxMsgCommonDto, String agToken, String asToken) {
        //微信小程序所需参数
        String domain = wxMsgCommonDto.getDomain();
        String companyUuid = wxMsgCommonDto.getCompanyUuid();
        String companyName = wxMsgCommonDto.getCompanyName();
        String oldCustomerStatus = statusMap.get("oldCustomerStatus");
        String newCustomerStatus = statusMap.get("newCustomerStatus");
        String oldConfirmStatus = statusMap.get("oldConfirmStatus");
        String newConfirmStatus = statusMap.get("newConfirmStatus");
        String remark = wxMsgCommonDto.getRemark();
        String weappMsgFailure = wxMsgCommonDto.getWeappMsgFailure();

        //签约成功,发送短信
        logger.info("发送交易短信：交易状态码" + newConfirmStatus);
        Map<String, String> weappAgencyMsgMap = new HashMap<>();
        try {
            weappAgencyMsgMap.put("id", String.valueOf(customerPremises.getId()));
            weappAgencyMsgMap.put("staffId", String.valueOf(customerPremises.getStaffId()));
            weappAgencyMsgMap.put("premisesId", String.valueOf(customerPremises.getPremisesId()));
            weappAgencyMsgMap.put("customerName", customerPremises.getName());
            weappAgencyMsgMap.put("customerPhone", customerPremises.getMobile());
            weappAgencyMsgMap.put("createTime", DateUtils.DateToString(customerPremises.getCreateTime(), DateStyle.YYYY_MM_DD_HH_MM_SS));
            weappAgencyMsgMap.put("hopeVisitTime", Objects.isNull(customerPremises.getHopeVisitTime()) ? "" : DateUtils.DateToString(customerPremises.getHopeVisitTime(), DateStyle.YYYY_MM_DD_HH_MM_SS));
            weappAgencyMsgMap.put("changeTime", DateUtils.DateToString(new Date(), DateStyle.YYYY_MM_DD_HH_MM_SS));
            weappAgencyMsgMap.put("changeStatus", newConfirmStatus);
            weappAgencyMsgMap.put("failureDesc", weappMsgFailure);
            weappAgencyMsgMap.put("remark", remark);
            weappAgencyMsgMap.put("companyUuid", companyUuid);

            //报备审核成功小程序消息通知
            if (ConfirmStatusEnum.sign.getNo().equals(newConfirmStatus)) {
                wxTemplateMsgService.sendSignSuccessTemplateMsg(agToken, asToken, customerPremises, companyName, wxMsgCommonDto);
                //报备签约成功小程序消息通知
                weAppMessageService.sendWeAppAgencyMsg(weappAgencyMsgMap, WeAppSendTypeEnum.AGENCY_TRADE_SUCCESS.getNo());
            } else if (ConfirmStatusEnum.payDeposit.getNo().equals(newConfirmStatus)) {
                //发送认筹成功微信模板消息
                wxTemplateMsgService.sendPayDepositSuccessTemplateMsg(agToken, asToken, companyUuid,
                        domain, customerPremises.getId(),
                        String.valueOf(customerPremises.getPremisesId()),
                        String.valueOf(customerPremises.getStaffId()),
                        customerPremises.getName(), customerPremises.getMobile());
                //报备认筹成功小程序消息通知
                weAppMessageService.sendWeAppAgencyMsg(weappAgencyMsgMap, WeAppSendTypeEnum.AGENCY_TRADE_SUCCESS.getNo());
            } else if (ConfirmStatusEnum.subscribe.getNo().equals(newConfirmStatus)) {
                //发送认购成功微信模板消息
                wxTemplateMsgService.sendSubscribeSuccessTemplateMsg(agToken, asToken, companyUuid,
                        domain, customerPremises.getId(),
                        String.valueOf(customerPremises.getPremisesId()),
                        String.valueOf(customerPremises.getStaffId()),
                        customerPremises.getName(), customerPremises.getMobile());
                //报备认购成功小程序消息通知
                weAppMessageService.sendWeAppAgencyMsg(weappAgencyMsgMap, WeAppSendTypeEnum.AGENCY_TRADE_SUCCESS.getNo());
            } else if (ConfirmStatusEnum.sign_fail.getNo().equals(newConfirmStatus) || CustomerStatusEnum.no_valid.getNo().equals(newCustomerStatus)) {
                //发送交易失败微信模板消息
                wxTemplateMsgService.sendDealFailTemplateMsg(
                        agToken, asToken, wxMsgCommonDto, customerPremises.getId(),
                        String.valueOf(customerPremises.getPremisesId()),
                        String.valueOf(customerPremises.getStaffId()),
                        customerPremises.getName(), customerPremises.getMobile(), remark);
                //报备交易失败小程序消息通知
                weAppMessageService.sendWeAppAgencyMsg(weappAgencyMsgMap, WeAppSendTypeEnum.AGENCY_TRADE_FAILURE.getNo());
            }
        }catch (Exception e){
            logger.error("异步发送消息失败,报备id:{}",customerPremises.getId());
            e.printStackTrace();
        }
    }

    @Override
    @Async
    public void syncReportStatusToV10(String optType, SyncReportStatusToV10Dto toV10Dto, Map<String, String> statusMap, List<AffixDto> affixList) {
        try {
            Long reportId = toV10Dto.getReportId();
            String operFollowRemark = toV10Dto.getOperFollowRemark();
            String oldCustomerStatus = statusMap.get("oldCustomerStatus");
            String newCustomerStatus = statusMap.get("newCustomerStatus");
            String oldConfirmStatus = statusMap.get("oldConfirmStatus");
            String newConfirmStatus = statusMap.get("newConfirmStatus");

            ReportExternalDto reportExternalDto = new ReportExternalDto();
            reportExternalDto.setReportId(reportId);
            reportExternalDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
            List<ReportExternal> reportExternalList = reportExternalService.selectListByDto(reportExternalDto);

            if (CollectionUtils.isEmpty(reportExternalList)) {
                return;
            }
            String uuid = reportExternalList.get(0).getReportUuid();
            if (StringUtils.isEmpty(uuid)) {
                return;
            }

            SyncFollowAndAffixReqDto syncReqDto = new SyncFollowAndAffixReqDto();
            V10IntentionFollowDto followVo = new V10IntentionFollowDto();
            followVo.setIntentionUuid(uuid);
            followVo.setOperationType(optType);
            followVo.setRemark(toV10Dto.getRemark());
            followVo.setOldAuditStatus(oldCustomerStatus);
            followVo.setNewAuditStatus(newCustomerStatus);
            syncReqDto.setFollowVo(followVo);

            if (!CollectionUtils.isEmpty(affixList)) {
                List<V10AffixDto> v10AffixList = new ArrayList<>();
                for (AffixDto affix : affixList) {
                    V10AffixDto v10AffixDto = new V10AffixDto();
                    v10AffixDto.setAffixName(affix.getAffixName());
                    v10AffixDto.setAffixType(affix.getAffixType());
                    v10AffixDto.setChannelAffixUuid(affix.getAffixUuid());
                    v10AffixDto.setIntentionUuid(uuid);
                    v10AffixDto.setIsQiNiu(affix.getIsQiNiu());
                    v10AffixDto.setUrl(affix.getUrl());
                    v10AffixDto.setFileType(affix.getFileType());
                    v10AffixList.add(v10AffixDto);
                }
                syncReqDto.setAffixList(v10AffixList);
            }

            if (OperationTypeEnum.OPERATIONTYPE_3.getCode().equals(optType)) {
                UpdateFirsthandIntentionAuditStatusReqDto v10ReqDto = new UpdateFirsthandIntentionAuditStatusReqDto();
                v10ReqDto.setIntentionUuid(uuid);
                v10ReqDto.setAuditStatus(newCustomerStatus);
                v10ReqDto.setOldAuditStatus(oldCustomerStatus);
                v10ReqDto.setRemark(operFollowRemark);
                v10ReqDto.setVisitTime(toV10Dto.getVisitTime());
                v10ReqDto.setReportPeriodTime(toV10Dto.getReportPeriodTime());
                v10ReqDto.setAdviserName(toV10Dto.getAdviserName());
                v10ReqDto.setAdviserPhone(toV10Dto.getAdviserPhone());
                v10BindService.updateFirsthandIntentionAuditStatus(v10ReqDto, syncReqDto);
            } else if (OperationTypeEnum.OPERATIONTYPE_2.getCode().equals(optType)) {
                UpdateFirsthandIntentionTradeStatusReqDto v10ReqDto = new UpdateFirsthandIntentionTradeStatusReqDto();
                v10ReqDto.setIntentionUuid(uuid);
                //楼栋
                if (StringUtils.isNotEmpty(toV10Dto.getBuildingName())) {
                    v10ReqDto.setBuildingCode(toV10Dto.getBuildingName());
                }
                //房号
                if (StringUtils.isNotEmpty(toV10Dto.getRoomName())) {
                    v10ReqDto.setRoomCode(toV10Dto.getRoomName());
                }
                //计价面积
                if (StringUtils.isNotEmpty(toV10Dto.getValuationArea())) {
                    v10ReqDto.setDealArea(toV10Dto.getValuationArea());
                }
                //成交总额
                if (StringUtils.isNotEmpty(toV10Dto.getDealAmount())) {
                    v10ReqDto.setDealAmount(toV10Dto.getDealAmount());
                }
                //认购金额
                if (StringUtils.isNotEmpty(toV10Dto.getSignatureAmount())) {
                    if (!"weihaianbangruidedic_company1413027af".equals(toV10Dto.getCompanyUuid()) && !"chengdouqiaofangxinx_companyf9413b81c".equals(toV10Dto.getCompanyUuid())) {
                        v10ReqDto.setSignatureAmount(toV10Dto.getSignatureAmount());
                    }
                }
                DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

                v10ReqDto.setTradeDate(dateTimeFormatter.format(LocalDateTime.now()));
                v10ReqDto.setRemark(operFollowRemark);
                v10ReqDto.setTradeStatus(newConfirmStatus);
                v10ReqDto.setOldTradeStatus(oldConfirmStatus);
                v10ReqDto.setAdviserName(toV10Dto.getAdviserName());
                v10ReqDto.setAdviserPhone(toV10Dto.getAdviserPhone());
                v10ReqDto.setDealClientName(toV10Dto.getDealClientName());
                v10BindService.updateFirsthandIntentionTradeStatus(v10ReqDto, syncReqDto);
            }
        }catch (Exception e){
            logger.error("异步同步V10报备信息失败");
            e.printStackTrace();
        }
    }

    @Override
    public void syncResetReportStatusToV10(String optType, SyncReportStatusToV10Dto toV10Dto, Map<String, String> statusMap, List<AffixDto> affixList) {
        Long reportId = toV10Dto.getReportId();
        String newCustomerStatus = statusMap.get("newCustomerStatus");
        String newConfirmStatus = statusMap.get("newConfirmStatus");

        ReportExternalDto reportExternalDto = new ReportExternalDto();
        reportExternalDto.setReportId(reportId);
        reportExternalDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
        List<ReportExternal> reportExternalList = reportExternalService.selectListByDto(reportExternalDto);

        if (CollectionUtils.isEmpty(reportExternalList)) {
            return;
        }
        String uuid = reportExternalList.get(0).getReportUuid();
        if (StringUtils.isEmpty(uuid)) {
            return;
        }

        SyncChannelIntentionStatusDTO resetSyncDTO = new SyncChannelIntentionStatusDTO();
        resetSyncDTO.setIntentionUuid(uuid);
        resetSyncDTO.setRemark(toV10Dto.getRemark());
        if (OperationTypeEnum.OPERATIONTYPE_3.getCode().equals(optType)) {
            resetSyncDTO.setChannelStatusType("1");
            resetSyncDTO.setStatus(newCustomerStatus);

        } else if (OperationTypeEnum.OPERATIONTYPE_2.getCode().equals(optType)) {
            resetSyncDTO.setChannelStatusType("2");
            resetSyncDTO.setStatus(newConfirmStatus);
            resetSyncDTO.setBuildingCode(toV10Dto.getBuildingName());
            resetSyncDTO.setRoomCode(toV10Dto.getRoomName());
            resetSyncDTO.setDealArea(toV10Dto.getValuationArea());
            //同步置业顾问
            resetSyncDTO.setAdviserName(toV10Dto.getAdviserName());
            resetSyncDTO.setAdviserPhone(toV10Dto.getAdviserPhone());
            if(ConfirmStatusEnum.subscribe.getNo().equals(newConfirmStatus)){
                resetSyncDTO.setDealAmount(toV10Dto.getSignatureAmount());
            }
            if(ConfirmStatusEnum.sign.getNo().equals(newConfirmStatus)){
                resetSyncDTO.setDealAmount(toV10Dto.getDealAmount());
                resetSyncDTO.setSignTime(new Date());
            }
            if(ConfirmStatusEnum.subscribe.getNo().equals(newConfirmStatus)
                    || ConfirmStatusEnum.sign.getNo().equals(newConfirmStatus)
                    || ConfirmStatusEnum.sign_fail.getNo().equals(newConfirmStatus)){
                resetSyncDTO.setTradeDate(DateUtils.DateToString(new Date(), DateStyle.YYYY_MM_DD_HH_MM_SS));
            }
        }
        v10BindService.syncChannelIntentionStatus(resetSyncDTO);
    }

    @Override
    public void sendSignCPSms(PartnerInfo assistantPi, CustomerPremises customerPremises) {
        //查询楼盘相关案场助手人员,发短信用
        CaseMemberDto cmDto = new CaseMemberDto();
        cmDto.setPremisesId(customerPremises.getPremisesId());
        cmDto.setPiStatus(MechanismStatusEnum.enable.getNo());
        cmDto.setSmsStatus("1");
        List<CaseMember> cmList = new ArrayList<CaseMember>();
        boolean flag = companyService.getMessageFlag(assistantPi.getHigherid());
        logger.info("商户 [ " + assistantPi.getHigherid() + "], 短信通道是否打开: " + flag);
        if (flag) {
            //需要发短信，就查询接收短信相关人员
            cmList = caseMemberService.selectListByDto(cmDto);
        }
        PartnerInfo reportPartner = partnerInfoService.selectById(customerPremises.getStaffId());
        Premises premises = premisesService.selectSimpleById(customerPremises.getPremisesId());
        //发送短信
        try {
            if (null != cmList && cmList.size() > 0) {
                //报备客户,给楼盘对应的管理员发送短信
                String smsSwitch = smsUtil.getSmsSwitch();
                if (StringUtils.isNotEmpty(smsSwitch) && "T".equals(smsSwitch)) {
                    String smsTemp = SMSTypeEnum.TYPE_01.getNo();
                    DictionaryDto dicDto = new DictionaryDto();
                    dicDto.setDicType(smsTemp);
                    Dictionary dic = dictionaryService.selectByDto(dicDto);
                    if (null != dic) {
                        // 添加报备人进来,一起发送短信
                        // 将经纪人的Id、楼盘的公司存入到CaseMember
                        CaseMember reportCm = new CaseMember();
                        reportCm.setPartnerId(reportPartner.getId());
                        reportCm.setCompanyId(premises.getCompanyId());
                        cmList.add(reportCm);
                        String reportPi = String.valueOf(reportPartner.getId());
                        for (CaseMember cm : cmList) {
                            String receiveMobile = "";
                            PartnerInfo cmPi = partnerInfoService.selectById(cm.getPartnerId());
                            if (null != cmPi) {
                                receiveMobile = cmPi.getPhone();
                            }
                            //如果是报备人的时候 receiveMobile 先从报备表里面取
                            if (cm.getId() == null && cm.getPartnerId().equals(reportPartner.getId())) {
                                if (StringUtils.isNotBlank(customerPremises.getReportPhone())) {
                                    receiveMobile = customerPremises.getReportPhone();
                                }
                            }
                            if (StringUtils.isEmpty(receiveMobile)) {
                                continue;
                            }

                            long smsCompany = cmPi.getHigherid();
                            if (reportPi.equals(String.valueOf(cm.getPartnerId()))) {
                                smsCompany = cm.getCompanyId();
                            }

                            //客户姓名
                            String cusName = customerPremises.getName();
                            //客户手机号
                            String cusPhone = customerPremises.getMobile();
                            //到访时间: 当前时间
                            String currTime = DateUtils.DateToString(Calendar.getInstance().getTime(), DateStyle.YYYY_MM_DD_HH_MM_SS);
                            //楼盘名称
                            String premisesName = premises.getName();
                            //获取短信设置,功能已变更.设置已用于定制化号码验真.此处不能保留
                            Map<String, String> smsSettingMap = null;
                            Map<String, String> qfSmsMap = new HashMap<>();
                            qfSmsMap.put("key1", cusName);
                            qfSmsMap.put("key2", cusPhone);
                            qfSmsMap.put("key3", currTime);
                            qfSmsMap.put("key4", premisesName);
                            Map<String, Object> returnMap = smsUtil.sendMessage("", receiveMobile, QfSmsTemplateEnum.SMS_SIGNED_SUCCESS.getId(), smsSettingMap, qfSmsMap);
                            boolean sendStatus = (Boolean) returnMap.get("sendStatus");
                            String sendRes = String.valueOf(returnMap.get("sendRes"));
                            SmsHistoryDto smsHis = new SmsHistoryDto();
                            String smsContent = "签约成功！签约客户：%s %s，于%s签约%s，请及时进行业务跟进";
                            smsContent = String.format(smsContent, cusName, cusPhone, currTime, premisesName);
                            smsHis.setSender(smsUtil.getUserName());
                            if (null != smsSettingMap) {
                                smsHis.setSender(smsSettingMap.get("userName"));
                            }
                            smsHis.setReceiver(receiveMobile);
                            smsHis.setContent(smsContent);
                            smsHis.setSendStatus(sendStatus ? SendStatusEnum.SUCCESS.getNo() : SendStatusEnum.FAILURE.getNo());
                            smsHis.setSendRes(sendRes);
                            smsHis.setMerchantId(smsCompany);
                            smsHis.setRemark("报备签约成功!");
                            smsHis.setCreateUserId(assistantPi.getId());
                            if (returnMap.containsKey("orderUuid")) {
                                smsHis.setOrderUuid(String.valueOf(returnMap.get("orderUuid")));
                            }
                            if (returnMap.containsKey("platform")) {
                                smsHis.setPlatform(String.valueOf(returnMap.get("platform")));
                            }
                            smsHistoryService.create(smsHis);
                        }
                    }
                }
            }
        } catch (Exception e) {
            logger.error("isExistsInM2 error: {}", e);
        }
    }

    /**
     * 利用Jackson 判断字符是否为合法json
     * @param jsonInString
     * @return
     */
    public final static boolean isJSONValid(String jsonInString) {
        try {
            final ObjectMapper mapper = new ObjectMapper();
            mapper.readTree(jsonInString);
            return true;
        } catch (IOException e) {
            return false;
        }
    }

    @Override
    public void syncM2DealInfo(UpdateSaleStatusReqDto reqDto, CustomerPremisesDto customerPremisesDto) {
        CustomerPremises cusPre = customerPremisesService.selectByIdForLock(Long.valueOf(reqDto.getRecommendedChannelId()));
        CustomerPremisesDto cpDto = new CustomerPremisesDto();
        boolean update = false;
        if(StringUtils.isNotEmpty(reqDto.getDealClientName())){
            cpDto.setDealClientName(reqDto.getDealClientName());
            update = true;
        }
        if(StringUtils.isNotEmpty(reqDto.getAdviserName()) && StringUtils.isNotEmpty(reqDto.getAdviserPhone())){
            // 根据姓名和电话查询
            EstateAdviser entity = new EstateAdviser();
            entity.setPremisesId(cusPre.getPremisesId());
            entity.setName(reqDto.getAdviserName());
            entity.setPhone(reqDto.getAdviserPhone());
            EstateAdviser estateAdviser =  estateAdviserService.selectOne(entity);
            //如果没有，插入一条，返回ID
            if(estateAdviser == null){
                estateAdviser = new EstateAdviser();
                estateAdviser.setName(reqDto.getAdviserName());
                estateAdviser.setPhone(reqDto.getAdviserPhone());
                estateAdviser.setPremisesId(cusPre.getPremisesId());
                estateAdviser.setAdviserUuid(UUID.randomUUID().toString());
                estateAdviser.setDeleted(DelFlagEnum.UNDEL.getNo());
                estateAdviserService.add(estateAdviser);
            }
            // 如果有，更新报备置业顾问ID
            cpDto.setAdviserUuid(estateAdviser.getAdviserUuid());
            update = true;
        }
        if(update){
            cpDto.setId(cusPre.getId());
            logger.info("syncM2DealInfo   M2同步置业顾问，成交客户信息 {}",JSONObject.toJSONString(cpDto));
            customerPremisesService.update(cpDto);
        }
    }

    @Override
    public void syncExchangeHousesToV10(String optType, SyncReportStatusToV10Dto toV10Dto, Map<String, String> statusMap, List<AffixDto> affixList) {
        Long reportId = toV10Dto.getReportId();
        String operFollowRemark = toV10Dto.getOperFollowRemark();
        String oldCustomerStatus = statusMap.get("oldCustomerStatus");
        String newCustomerStatus = statusMap.get("newCustomerStatus");
        String oldConfirmStatus = statusMap.get("oldConfirmStatus");
        String newConfirmStatus = statusMap.get("newConfirmStatus");

        ReportExternalDto reportExternalDto = new ReportExternalDto();
        reportExternalDto.setReportId(reportId);
        reportExternalDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
        List<ReportExternal> reportExternalList = reportExternalService.selectListByDto(reportExternalDto);

        if (CollectionUtils.isEmpty(reportExternalList)) {
            return;
        }
        String uuid = reportExternalList.get(0).getReportUuid();
        if (StringUtils.isEmpty(uuid)) {
            return;
        }

        SyncFollowAndAffixReqDto syncReqDto = new SyncFollowAndAffixReqDto();
        V10IntentionFollowDto followVo = new V10IntentionFollowDto();
        followVo.setIntentionUuid(uuid);
        followVo.setOperationType(optType);
        followVo.setRemark(toV10Dto.getRemark());
        followVo.setOldAuditStatus(oldCustomerStatus);
        followVo.setNewAuditStatus(newCustomerStatus);
        syncReqDto.setFollowVo(followVo);

        if (!CollectionUtils.isEmpty(affixList)) {
            List<V10AffixDto> v10AffixList = new ArrayList<>();
            for (AffixDto affix : affixList) {
                V10AffixDto v10AffixDto = new V10AffixDto();
                v10AffixDto.setAffixName(affix.getAffixName());
                v10AffixDto.setAffixType(affix.getAffixType());
                v10AffixDto.setChannelAffixUuid(affix.getAffixUuid());
                v10AffixDto.setIntentionUuid(uuid);
                v10AffixDto.setIsQiNiu(affix.getIsQiNiu());
                v10AffixDto.setUrl(affix.getUrl());
                v10AffixDto.setFileType(affix.getFileType());
                v10AffixList.add(v10AffixDto);
            }
            syncReqDto.setAffixList(v10AffixList);
        }

        UpdateFirsthandIntentionTradeStatusReqDto v10ReqDto = new UpdateFirsthandIntentionTradeStatusReqDto();
        v10ReqDto.setIntentionUuid(uuid);
        //楼栋
        if (StringUtils.isNotEmpty(toV10Dto.getBuildingName())) {
            v10ReqDto.setBuildingCode(toV10Dto.getBuildingName());
        }
        //房号
        if (StringUtils.isNotEmpty(toV10Dto.getRoomName())) {
            v10ReqDto.setRoomCode(toV10Dto.getRoomName());
        }
        //计价面积
        if (StringUtils.isNotEmpty(toV10Dto.getValuationArea())) {
            v10ReqDto.setDealArea(toV10Dto.getValuationArea());
        }
        //成交总额
        if (StringUtils.isNotEmpty(toV10Dto.getDealAmount())) {
            v10ReqDto.setDealAmount(toV10Dto.getDealAmount());
        }
        //认购金额
        if (StringUtils.isNotEmpty(toV10Dto.getSignatureAmount())) {
            if (!"weihaianbangruidedic_company1413027af".equals(toV10Dto.getCompanyUuid()) && !"chengdouqiaofangxinx_companyf9413b81c".equals(toV10Dto.getCompanyUuid())) {
                v10ReqDto.setSignatureAmount(toV10Dto.getSignatureAmount());
            }
        }
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

        v10ReqDto.setTradeDate(dateTimeFormatter.format(LocalDateTime.now()));
        v10ReqDto.setRemark(operFollowRemark);
        v10ReqDto.setTradeStatus(newConfirmStatus);
        v10ReqDto.setOldTradeStatus(oldConfirmStatus);
        v10ReqDto.setAdviserName(toV10Dto.getAdviserName());
        v10ReqDto.setAdviserPhone(toV10Dto.getAdviserPhone());
        v10ReqDto.setDealClientName(toV10Dto.getDealClientName());
        v10BindService.exchangeHouses(v10ReqDto, syncReqDto);
    }

    @Override
    public void syncReportRevisitToV10(SyncReportRevisitToV10Dto toV10Dto, CustomerPremises customerPremises, List<AffixDto> affixList) {
        ReportExternalDto reportExternalDto = new ReportExternalDto();
        reportExternalDto.setReportId(customerPremises.getId());
        reportExternalDto.setIsDeleted(DelFlagEnum.UNDEL.getNo());
        List<ReportExternal> reportExternalList = reportExternalService.selectListByDto(reportExternalDto);

        if (CollectionUtils.isEmpty(reportExternalList)) {
            return;
        }
        String uuid = reportExternalList.get(0).getReportUuid();
        if (StringUtils.isEmpty(uuid)) {
            return;
        }

        SyncFollowAndAffixReqDto syncReqDto = new SyncFollowAndAffixReqDto();
        V10IntentionFollowDto followVo = new V10IntentionFollowDto();
        followVo.setIntentionUuid(uuid);
        followVo.setOperationType(OperationTypeEnum.OPERATIONTYPE_8.getCode());
        followVo.setRemark(toV10Dto.getRemark());
        followVo.setOldAuditStatus(customerPremises.getCustomerStatus());
        followVo.setNewAuditStatus(customerPremises.getCustomerStatus());
        syncReqDto.setFollowVo(followVo);

        if (!CollectionUtils.isEmpty(affixList)) {
            List<V10AffixDto> v10AffixList = new ArrayList<>();
            for (AffixDto affix : affixList) {
                V10AffixDto v10AffixDto = new V10AffixDto();
                v10AffixDto.setAffixName(affix.getAffixName());
                v10AffixDto.setAffixType(affix.getAffixType());
                v10AffixDto.setChannelAffixUuid(affix.getAffixUuid());
                v10AffixDto.setIntentionUuid(uuid);
                v10AffixDto.setIsQiNiu(affix.getIsQiNiu());
                v10AffixDto.setUrl(affix.getUrl());
                v10AffixDto.setFileType(affix.getFileType());
                v10AffixList.add(v10AffixDto);
            }
            syncReqDto.setAffixList(v10AffixList);
        }

        FirsthandIntentionRevisitReqDto v10ReqDto = new FirsthandIntentionRevisitReqDto();
        v10ReqDto.setIntentionUuid(uuid);
        v10ReqDto.setVisitTime(toV10Dto.getVisitTime());
        v10ReqDto.setReportPeriodTime(toV10Dto.getReportPeriodTime());
        v10BindService.updateFirsthandIntentionRevisit(v10ReqDto, syncReqDto);
    }
}
